#include "znx_http_conn.h"


static void
znx_http_net_conn_close_handler(znx_conn_t *c)
{
    znx_http_conn_t *hc = c->data;

    if (c->ssl) {
        c->ssl->handler = znx_http_net_conn_close_handler;
        if (znx_ssl_shutdown(c) == ZNX_AGAIN) {
            return;
        }
    }

    znx_event_loop_remove_conn(c);
    znx_conn_close_and_free(c);

    if (!hc) {
        return;
    }

    hc->c = NULL;
    hc->close_handler(hc);
}


void znx_http_conn_close(znx_http_conn_t *hc,
    znx_http_conn_handler close_handler)
{
    if (close_handler != NULL) {
        ZNX_HTTP_LOG_FATAL(hc->hlog, "close_handler must be set");
    }

    hc->close_handler = close_handler;

    if (hc->c->type == ZNX_TCP_CONN ||
        hc->c->type == ZNX_UDP_CONN)
    {
        znx_http_net_conn_close_handler(hc->c);
        return;
    }

    // ....
}


static inline void
znx_http_net_conn_event(znx_http_conn_t *hc, znx_event_t *event)
{
    if (event == &hc->c->read) {
        if (hc->read_active || event->timer_callback) {
            event->timer_callback = 0;
            hc->read_handler(hc);
            return;
        }

        znx_event_loop_disable_read(hc->c);
        return;
    }

    if (hc->write_active || event->timer_callback) {
        event->timer_callback = 0;
        hc->write_handler(hc);
        return;
    }

    znx_event_loop_disable_write(hc->c);
}


void
znx_http_conn_event_handler(znx_event_t *event)
{
    znx_conn_t              *c;
    znx_http_conn_t         *hc;

    c = event->data;
    hc = c->data;

    if (hc->c->type == ZNX_TCP_CONN ||
        hc->c->type == ZNX_UDP_CONN)
    {
        znx_http_net_conn_event(hc, event);
    }

    return;
}
